package hz;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class TestCommunicator {

	Communicator a, b;

	@Before
	public void init() {
		a = new Communicator();
		b = new Communicator();
	}

	// @Test
	public void testSignUpAndIn() {
		int ida = a.signUp("whoami", "password");
		Assert.assertTrue(ida > 0);

		int idb = b.signUp("whoami", "password");
		Assert.assertTrue(idb <= 0);

		idb = b.signUp("iamroot", "password");
		Assert.assertTrue(idb == ida + 1);

		Assert.assertTrue(a.signIn("whoami", "password") > 0);
	}

	//@Test
	public void createandplay() {
		int bid = b.signIn("iamroot", "password");
		Assert.assertTrue(bid > 0);

		Room room = b.lsRooms()[0];
		b.joinRoom(room);

		int[] pos = new int[2];
		b.waitForMove(pos);

		b.move(0, 2);
		b.waitForMove(pos);

		b.move(0, 1);
	}

	@Test
	public void joinandplay() {
		int bid = b.signIn("iamroot", "password");
		Assert.assertTrue(bid > 0);

		b.createRoom(bid, "gogaoailinger", "123");
		b.waitForRival();

		b.move(0, 0);
		int[] pos = new int[2];
		b.waitForMove(pos);

		b.move(0, 1);
		b.waitForMove(pos);

		b.move(0, 2);

	}

	/**
	 * A simple scenario. please refer to the comments.
	 */
	// @Test
	public void testRoom() {

		// a and b sign in
		int aid = a.signIn("whoami", "password");
		int bid = b.signIn("iamroot", "password");
		Assert.assertTrue(aid > 0);
		Assert.assertTrue(bid > 0);

		// a asks server do we have any available game rooms?
		Assert.assertEquals(0, a.lsRooms().length);
		// no available room, so she creates one
		Assert.assertTrue(a.createRoom(aid, "whoami", "hello").getId() > 0);

		// b lists rooms and chooses the 1st one
		Assert.assertEquals(1, b.lsRooms().length);
		Room room = b.lsRooms()[0];
		// b enters wrong passwd
		Assert.assertFalse(b.joinRoom(room, "world"));
		Assert.assertTrue(b.joinRoom(room, "hello"));
		// b asks for a's information
		User u = b.getUser(room.getAid());
		Assert.assertEquals("whoami", u.getUserid());

		// a waits for b and asks for b's information
		int rivalId = a.waitForRival();
		Assert.assertTrue(rivalId == bid);
		User u2 = a.getUser(rivalId);
		Assert.assertEquals("iamroot", u2.getUserid());

		// a moves to (1, 0) first
		a.move(1, 0);

		// lets see if b is aware of a's movement
		// b waits for a's move
		int[] pos = new int[2];
		b.waitForMove(pos);

		Assert.assertEquals(1, pos[0]);
		Assert.assertEquals(0, pos[1]);

		// a moves to (1, 0) next, failed coz its not her turn
		Assert.assertTrue("oops".equals(a.move(1, 1)));

		// b moves
		b.move(0, 1);
		a.waitForMove(pos);

		// now a
		a.move(1, 1);
		b.waitForMove(pos);

		// now b
		b.move(0, 0);
		a.waitForMove(pos);

		// now a move to (1, 2), she wins!
		Assert.assertTrue(a.move(1, 2).equals("youwin"));
		// poor b gets a `you lose' msg from server
		Assert.assertTrue(b.waitForMove(pos).equals("youlose"));

		// ok, 2nd round

		a.createRoom(aid, "whoami2");
		Room room2 = b.lsRooms()[0];
		b.joinRoom(room2);
		a.waitForRival();

		// a abandoned.
		a.abandon();
		String status = b.waitForMove(pos);
		// so b recv an 'abandoned' msg.
		Assert.assertEquals("abandoned", status);
	}

	@After
	public void close() {
		a.close();
		b.close();
	}
}
